/* Includes ------------------------------------------------------------------*/
#include "SystemTick.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define TIM4_PERIOD             124
#define MAX_FUNCTION_SUPPORT    4

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
__IO bool   s_SysIntFlag = false;
void_f      s_pTimerActiveFunction[MAX_FUNCTION_SUPPORT];
U8          s_FunctionCount = 0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public variables ----------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/


INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
    /* Cleat Interrupt Pending bit */
    TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
    s_SysIntFlag = true;
}


void SysTick_Init(void)
{
    /* TIM4 configuration:
    - TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
    clock used is 16 MHz / 128 = 125 000 Hz
    - With 125 000 Hz we can generate time base:
    max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
    min time base is 0.016 ms if TIM4_PERIOD = 1   --> (  1 + 1) / 125000 = 0.016 ms
    - In this example we need to generate a time base equal to 1 ms
    so TIM4_PERIOD = (0.001 * 125000 - 1) = 124 */

    /* Time base configuration */
    TIM4_TimeBaseInit(TIM4_PRESCALER_128, TIM4_PERIOD);
    /* Clear TIM4 update flag */
    TIM4_ClearFlag(TIM4_FLAG_UPDATE);
    /* Enable update interrupt */
    TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);

    /* Enable TIM4 */
    TIM4_Cmd(ENABLE);
}


bool SysTick_Registration(void_f pFunction)
{
    bool rc = false;

    if (MAX_FUNCTION_SUPPORT >= s_FunctionCount)
    {
        s_pTimerActiveFunction[s_FunctionCount] = pFunction;
        ++s_FunctionCount;
        rc = true;
    }

    return (rc);
}


void SysTick_RunOne(void)
{
    U8 i;

    if (true == s_SysIntFlag)
    {
        s_SysIntFlag = false;

        for (i = 0; i < s_FunctionCount; i++)
        {
            ((void_f)s_pTimerActiveFunction[i])();
        }
    }
}
